package ph.com.gs3.chat.communicators;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import ph.com.gs3.chat.model.valueobject.application.APIResponse;
import ph.com.gs3.chat.model.valueobject.application.APIResponse.APIInvalidResponseException;
import ph.com.gs3.chat.utilities.FLLogger;
import ph.com.gs3.chat.utilities.FLLogger.LogType;

public class AuthenticationCommunicatorModule extends HttpCommunicatorModule {

	public static final String TAG = AuthenticationCommunicatorModule.class.getSimpleName();

	public static final int LOGIN_CONNECTION_TIMEOUT = 10000;	// 10s
	public static final int LOGIN_READ_TIMEOUT = 6000;	// 6s

	public AuthenticationCommunicatorModule(HttpCommunicator communicator, String server) {
		super(communicator, server);
	}

	public AuthenticationCommunicatorModule(HttpCommunicator communicator) {
		super(communicator, null);
	}

	/**
	 * Tries to login to the server using the specified email and password.
	 * 
	 * @param email
	 *            the email of the user that will login
	 * @param password
	 *            the password of the user that will login
	 * @return A JSONObject containing the status (containing SUCCESS or ERROR), error
	 *         (the error title), error_message, and results (user data such as id, email,
	 *         display_name, etc.)
	 * 
	 * @throws CommunicatorException
	 * @throws APIInvalidResponseException
	 */
	public APIResponse login(String email, String password) throws CommunicatorException,
	        APIInvalidResponseException {

		commonValidation();

		String url = server + "/API/login";

		// validate parameters
		if (email == null || email.isEmpty()) {
			throw new CommunicatorException("Email must not be empty");
		}

		if (password == null || password.isEmpty()) {
			throw new CommunicatorException("Password must not be empty");
		}

		Map<String, String> requestParams = new HashMap<String, String>();

		requestParams.put("email", email);
		requestParams.put("password", password);

		// login should have shorter connection timeout than usual
		communicator.setConnectionTimeout(LOGIN_CONNECTION_TIMEOUT);
		communicator.setReadTimeout(LOGIN_READ_TIMEOUT);

		return getResponse(url, requestParams);
	}

	/**
	 * Gets the currently logged in user in the formalistics server.
	 * 
	 * @return
	 * @throws CommunicatorException
	 * @throws APIInvalidResponseException
	 */
	public APIResponse getCurrentlyLoggedInUser() throws CommunicatorException,
	        APIInvalidResponseException {

		String url = server + "/API/current-user";

		communicator.setConnectionTimeout(LOGIN_CONNECTION_TIMEOUT);
		communicator.setReadTimeout(LOGIN_READ_TIMEOUT);

		// throws CommunicatorException
		String responseString = communicator.getResponseString(url, null, "POST");
		JSONObject responseJSON;
		try {
			responseJSON = new JSONObject(responseString);
		} catch (JSONException e) {
			FLLogger.log(TAG, LogType.ERROR,
			        "Failed to convert server response to JSON Object. The response was: "
			                + responseString + ".\n\n The error message was: " + e.getMessage());
			throw new APIInvalidResponseException(e);
		}

		// throws APIResponseException
		return new APIResponse(responseJSON);

	}

	/**
	 * Expose method for setting the server only for this class
	 */
	@Override
	public void setServer(String server) {
		super.setServer(server);
	}

}
